package com.smedi.ismedi.authoritymanagement.core.port.adapter.restful;


import com.smedi.ismedi.authority.starter.response.AuthorityAccessResponse;
import com.smedi.ismedi.authoritymanagement.api.dto.request.DataPermissionScopeRequest;
import com.smedi.ismedi.authoritymanagement.api.dto.response.FrameStructureResponse;
import com.smedi.ismedi.authoritymanagement.api.dto.response.WebClientStructureResponse;
import com.smedi.ismedi.authoritymanagement.api.feign.RemoteAuthorityAccessFeignApi;
import com.smedi.ismedi.authoritymanagement.core.application.query.CurrentUserQueryService;
import com.smedi.ismedi.authoritymanagement.core.application.query.vo.CurrentUserInfoVo;
import com.smedi.ismedi.authoritymanagement.core.application.query.vo.FrameStructureVo;
import com.smedi.ismedi.authoritymanagement.core.application.service.ClientLoginApplicationService;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.AuthorityAccess;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.FrameStructure;
import com.smedi.ismedi.authoritymanagement.core.port.adapter.convert.AdapterConverter;
import com.smedi.ismedi.web.starter.common.ResponseData;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @Author: xulinjun
 * @Date: 2021-6-29 18:57
 */
@Slf4j
@RestController
@AllArgsConstructor
public class AuthorityAccessController implements RemoteAuthorityAccessFeignApi {
    private final ClientLoginApplicationService clientLoginApplicationService;
    private final DozerUtil dozerUtil;
    private final AdapterConverter adapterConverter;

    private final CurrentUserQueryService currentUserQueryService;

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<AuthorityAccessResponse> getValidateTokenAndGetAuthorityAccessAndRefreshExpress(String token) {
        AuthorityAccess authorityAccess = clientLoginApplicationService.validateTokenAndGetAuthorityAccessAndRefreshExpress(token);
        return new ResponseData<AuthorityAccessResponse>().success(adapterConverter.authorityAccessToAuthorityAccessResponse(authorityAccess));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<Boolean> putBoundDataPermissionScope(DataPermissionScopeRequest dataPermissionScopeRequest) {
        clientLoginApplicationService.boundDataPermissionScope(dataPermissionScopeRequest.getToken(), dataPermissionScopeRequest.getDataScope());
        return new ResponseData<Boolean>().success(true);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<WebClientStructureResponse> getMenuInfrastructure(String rootCode) {
        List<FrameStructure> children = clientLoginApplicationService.getAllChildren();
        // 获取权限范围下的结构id
        List<Long> scopes = clientLoginApplicationService.getStructureIdsByScope(rootCode, children);

        // 获取整体框架结构
        FrameStructureVo frameStructureVo = clientLoginApplicationService.getMenuInfrastructureByScopeNew(rootCode, scopes, children);
        FrameStructureResponse response = dozerUtil.mapGeneric(frameStructureVo, FrameStructureResponse.class);

        // 获取整体路由
        List<String> routers = clientLoginApplicationService.queryMenuInfrastructureRoutersByScope(rootCode, scopes, children);

        WebClientStructureResponse webClientStructureResponse = new WebClientStructureResponse()
                .setStructureCode(frameStructureVo.getRootCode())
                .setStructureName(frameStructureVo.getRootName())
                .setStructureInfos(response.getChildren())
                .setRouters(routers);

        return new ResponseData<WebClientStructureResponse>().success(webClientStructureResponse);
    }

    @Override
    public ResponseData<AuthorityAccessResponse> getCurrentUserInfo() {
        CurrentUserInfoVo currentUserInfo = currentUserQueryService.getCurrentUserInfo();
        AuthorityAccessResponse authorityAccessResponse = adapterConverter.currentUserInfoVoToAuthorityAccessResponse(currentUserInfo);
        return new ResponseData<>().success(authorityAccessResponse);
    }
}
